home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 3 / Amiga Format CD03 (1996-07-04)(Future Publishing)(GB)(Track 1 of 6)[!][issue 1996-08].iso / comms / netsoftware / nameserver.lha / named / named.c < prev    next >
C/C++ Source or Header  |  1993-12-14  |  5KB  |  254 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <netdb.h>
  5. #include <sys/types.h>
  6. #include <sys/syslog.h>
  7. #include <sys/errno.h>
  8. #include <netinet/in.h>
  9. #include <arpa/nameser.h>
  10.  
  11. #include <exec/nodes.h>
  12. #include <exec/lists.h>
  13.  
  14. #include <proto/exec.h>
  15.  
  16. char VersionTag[]="\0$VER: JoranNameserver 0.3 (14.12.93)";
  17.  
  18. struct hostinfo {
  19.     struct MinNode Node;
  20.     char name[MAXDNAME];
  21.     LONG netnumber;
  22. };
  23. struct MinList hostlist;
  24. char Line[1024];
  25. char hostname[MAXHOSTNAMELEN];
  26. char *curnet="";
  27.  
  28. void readnamedhosts(void)
  29. {
  30.     FILE *f;
  31.     
  32.     f=fopen("AmiTCP:db/named.hosts","r");
  33.     if(!f)
  34.     {
  35.         perror("AmiTCP:db/named.hosts");
  36.         exit(1);
  37.     }
  38.     NewList((struct List *)&hostlist);
  39.     
  40.     while(fgets(Line,sizeof(Line),f))
  41.     {
  42.         char *p,*a[6];
  43.         char curdname[MAXDNAME];
  44.         LONG netnumber;
  45.         int i;
  46.         
  47.         if(p=strchr(Line,';')) *p='\0';        // Verwijderen commentaar
  48.         a[0]=strtok(Line,"\t\n ");
  49.         for(i=1;i<6;i++) a[i]=strtok(NULL,"\t\n ");
  50.         netnumber=-1;
  51.         for(i=0;i<6;i++) if(!a[i] || !strcmp(a[i],"IN")) break;
  52.         if(i>0) strcpy(curdname,a[0]);
  53.         if(i<4 && a[i+1] && !strcmp(a[i+1],"A")) netnumber=inet_addr(a[i+2]);
  54.  
  55.         if(netnumber!=-1)
  56.         {
  57.             struct hostinfo *hi;
  58.             
  59.             if(hi=malloc(sizeof(struct hostinfo)))
  60.             {
  61.                 strcpy(hi->name,curdname);
  62.                 if(hi->name[strlen(hi->name)-1]!='.') strcat(hi->name,curnet);
  63.                 else hi->name[strlen(hi->name)-1]='\0';
  64.                 hi->netnumber=netnumber;
  65. #ifdef DEBUG
  66.                 printf("add: %s(%s)\n",hi->name,Inet_NtoA(hi->netnumber));
  67. #endif
  68.                 AddTail((struct List *)&hostlist,(struct Node *)hi);
  69.             }
  70.         }
  71.     }
  72.     
  73.     fclose(f);
  74. }
  75.  
  76. void send_err(int s,char *msg,int msglen,struct sockaddr_in *to,LONG tolen,short rcode)
  77. {
  78.     HEADER *h;
  79.     
  80.     h=(HEADER *)msg+sizeof(HEADER);
  81.     h->qr=1;
  82.     h->rcode=rcode;
  83.     sendto(s,msg,msglen,0,(struct sockaddr *)to,tolen);
  84.     
  85. #ifdef DEBUG
  86.     switch(rcode)
  87.     {
  88.         case FORMERR:    puts("FORMERR send");break;
  89.         case SERVFAIL:    puts("FORMFAIL send");break;
  90.         case NXDOMAIN:    puts("NXDOMAIN send");break;
  91.         default:            puts("UNKNOWN ERROR send");break;
  92.     }
  93. #endif
  94. }
  95.  
  96. main()
  97. {
  98.     struct servent *sp;
  99.     struct sockaddr_in sin;
  100.     struct sockaddr_in from;
  101.     struct hostinfo *hp,*hi;
  102.     LONG fromlen;
  103.     char msg[PACKETSZ];
  104.     char *lmsg;
  105.     char dnbuf[MAXDNAME];
  106.     char *cp,*eom;
  107.     int msglen;
  108.     int s,n;
  109.     short type,class;
  110.     
  111.     sp=getservbyname("domain","udp");
  112.     if(!sp)
  113.     {
  114.         fprintf(stderr,"nameserver: tcp/nameserver: unknown service\n");
  115.         exit(1);
  116.     }
  117.     
  118.     s=socket(AF_INET,SOCK_DGRAM,0);
  119.     if(s==-1)
  120.     {
  121.         perror("nameserver: create socket");
  122.         exit(1);
  123.     }
  124.     
  125.     bzero(&sin,sizeof(sin));
  126.     sin.sin_port=sp->s_port;
  127.  
  128.     if(bind(s,(struct sockaddr *)&sin,sizeof(sin))==-1)
  129.     {
  130.         perror("nameserver: bind");
  131.         exit(1);
  132.     }
  133.     
  134.     if(gethostname(hostname,sizeof(hostname))==-1)
  135.     {
  136.         perror("nameserver: gethostname");
  137.         exit(1);
  138.     }
  139.     if(cp=strchr(hostname,'.')) curnet=cp;
  140.     
  141.     readnamedhosts();
  142.     
  143. #ifdef DEBUG
  144.     printf("nameserver started\n");
  145. #endif
  146.     for(;;)
  147.     {
  148.         fromlen=sizeof(from);
  149.         if((msglen=recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&from,&fromlen))==-1)
  150.         {
  151.             perror("nameserver: recvfrom");
  152.         }
  153.         else
  154.         {
  155.             HEADER *h;
  156.             h=(HEADER *)msg;
  157.             cp=msg+sizeof(HEADER);
  158.             eom=msg+msglen;
  159. #ifdef DEBUG
  160.             printf(    "datagram received:\n"
  161.                         "  from   : %s\n"
  162.                         "  opcode : %d\n"
  163.                         "  qdqount: %d\n"
  164.                         ,inet_ntoa(from.sin_addr)
  165.                         ,h->opcode
  166.                         ,h->qdcount
  167.             );
  168. #endif
  169.             switch(h->opcode)
  170.             {
  171.                 case QUERY:
  172.                     if(h->qdcount!=1 || h->ancount || h->nscount || h->arcount)
  173.                     {
  174.                         h->qdcount=0;
  175.                         h->ancount=0;
  176.                         h->nscount=0;
  177.                         h->arcount=0;
  178.                         send_err(s,msg,msglen,&from,fromlen,FORMERR);
  179.                         continue;
  180.                     }
  181.                     if((n=dn_expand(msg,eom,cp,dnbuf,sizeof(dnbuf)))<0)
  182.                     {
  183.                         send_err(s,msg,msglen,&from,fromlen,FORMERR);
  184.                         continue;
  185.                     }
  186.                     cp+=n;
  187.                     GETSHORT(type, cp);
  188.                     GETSHORT(class, cp);
  189.                     if(cp>eom)
  190.                     {
  191.                         send_err(s,msg,msglen,&from,fromlen,FORMERR);
  192.                         continue;
  193.                     }
  194. #ifdef DEBUG
  195.                     printf("  host   : %s\n",dnbuf);
  196.                     printf("  type   : %d\n",type);
  197.                     printf("  class  : %d\n",class);
  198. #endif
  199.                     if(type!=T_A || class!=C_IN)
  200.                     {
  201.                         send_err(s,msg,msglen,&from,fromlen,NOTIMP);
  202.                         continue;
  203.                     }
  204.                     
  205.                     hp=NULL;
  206.                     for(hi=(struct hostinfo *)hostlist.mlh_Head;hi!=(struct hostinfo *)&hostlist.mlh_Tail;hi=(struct hostinfo *)hi->Node.mln_Succ)
  207.                     {
  208.                         if(!strcmp(hi->name,dnbuf))
  209.                         {
  210.                             hp=hi;
  211.                             break;
  212.                         }
  213.                     }    
  214.  
  215.                     if(!hp)
  216.                     {
  217.                         send_err(s,msg,msglen,&from,fromlen,NXDOMAIN);
  218.                         continue;
  219.                     }
  220.                     
  221.                     lmsg=msg+sizeof(msg);
  222.                     if((n=dn_comp(dnbuf,cp,lmsg-cp,NULL,NULL))<0)
  223.                     {
  224.                         send_err(s,msg,msglen,&from,fromlen,SERVFAIL);
  225.                         continue;                        
  226.                     }
  227.                     cp+=n;
  228.                     if(cp+14>lmsg)
  229.                     {
  230.                         send_err(s,msg,msglen,&from,fromlen,SERVFAIL);
  231.                         continue;            
  232.                     }
  233.                     
  234.                     PUTSHORT(type, cp);
  235.                     PUTSHORT(class, cp);
  236.                     PUTLONG(100000,cp);
  237.                     PUTSHORT(sizeof(LONG),cp);
  238.                     PUTLONG(hi->netnumber,cp);
  239.                     
  240.                     h->qr=1;
  241.                     h->rcode=NOERROR;
  242.                     h->ancount=1;
  243.                     sendto(s,msg,cp-msg,0,(struct sockaddr *)&from,fromlen);
  244. #ifdef DEBUG
  245.                     printf("answer: %s(%s) send\n",dnbuf,Inet_NtoA(hi->netnumber));
  246. #endif
  247.                     break;
  248.                 default:
  249.                     send_err(s,msg,msglen,&from,fromlen,NOTIMP);
  250.             }
  251.         }
  252.     }
  253. }
  254.